home *** CD-ROM | disk | FTP | other *** search
/ Best Tools for JAVA / Best Tools for JAVA.iso / JAVA_ALL / JDBC / JDBC_011 / JAVA / SQL / DRIVERMA.JAV < prev    next >
Encoding:
Text File  |  1996-11-10  |  14.5 KB  |  424 lines

  1. /*
  2.  * Copyright (c) 1996 Sun Microsystems, Inc. All Rights Reserved.
  3.  *
  4.  * Permission to use, copy, modify, and distribute this software
  5.  * and its documentation for NON-COMMERCIAL purposes and without
  6.  * fee is hereby granted provided that this copyright notice
  7.  * appears in all copies. Please refer to the file "LICENSE"
  8.  * for further important copyright and licensing information.
  9.  *
  10.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
  11.  * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
  12.  * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  13.  * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
  14.  * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
  15.  * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
  16.  * 
  17.  * THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS ON-LINE
  18.  * CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE
  19.  * PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT
  20.  * NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE
  21.  * SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE
  22.  * SOFTWARE COULD LEAD DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE
  23.  * PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH RISK ACTIVITIES").  SUN
  24.  * SPECIFICALLY DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR
  25.  * HIGH RISK ACTIVITIES.
  26.  */
  27.  
  28. package java.sql;
  29.  
  30. /**
  31.  * <P>The DriverManager provides a basic service for managing a set of
  32.  * JDBC drivers.
  33.  *
  34.  * <P>As part of its initialization, the DriverManager class will
  35.  * attempt to load the driver classes referenced in the "jdbc.drivers"
  36.  * system property. This allows a user to customize the JDBC Drivers
  37.  * used by their applications. For example in your
  38.  * ~/.hotjava/properties file you might specify:
  39.  * <CODE>jdbc.drivers=foo.bah.Driver:wombat.sql.Driver:bad.taste.ourDriver</CODE>
  40.  *
  41.  * A program can also explicitly load JDBC drivers at any time. For
  42.  * example, the my.sql.Driver is loaded with the following statement:
  43.  * <CODE>Class.forName("my.sql.Driver");</CODE>
  44.  *
  45.  * <P>When getConnection is called the DriverManager will attempt to
  46.  * locate a suitable driver from amongst those loaded at
  47.  * initialization and those loaded explicitly using the same classloader
  48.  * as the current applet or application.
  49.  *
  50.  * @see Driver
  51.  * @see Connection 
  52.  */
  53. public class DriverManager {
  54.  
  55.     /**
  56.      * Attempt to establish a connection to the given database URL.
  57.      * The DriverManager attempts to select an appropriate driver from
  58.      * the set of registered JDBC drivers.
  59.      *
  60.      * @param url a database url of the form jdbc:<em>subprotocol</em>:<em>subname</em>
  61.      * @param info a list of arbitrary string tag/value pairs as
  62.      * connection arguments; normally at least a "user" and
  63.      * "password" property should be included
  64.      * @return a Connection to the URL 
  65.      */
  66.     public static synchronized Connection getConnection(String url, 
  67.             java.util.Properties info) throws SQLException {
  68.     if(url == null) {
  69.         throw new SQLException("The url cannot be null", "08001");
  70.     }
  71.  
  72.         println("DriverManager.getConnection(\"" + url + "\")");
  73.  
  74.         if (!initialized) {
  75.             initialize();
  76.         }
  77.  
  78.         // Figure out the current security context.
  79.         Object currentSecurityContext = getSecurityContext();
  80.  
  81.         // Walk through the loaded drivers attempting to make a connection.
  82.         // Remember the first exception that gets raised so we can reraise it.
  83.         SQLException reason = null;
  84.         for (int i = 0; i < drivers.size(); i++) {
  85.             DriverInfo di = (DriverInfo)drivers.elementAt(i);
  86.             // if the driver isn't part of the base system and doesn't come
  87.             // from the same security context as the current caller, skip it.
  88.             if (di.securityContext != null && 
  89.                         di.securityContext != currentSecurityContext) {
  90.                 println("    skipping: " + di);
  91.                 continue;
  92.             }
  93.             try {
  94.                 println("    trying " + di);
  95.                 Connection result = di.driver.connect(url, info);
  96.                 if (result != null) {
  97.                     // Success!
  98.                     println("getConnection returning " + di);
  99.                     return (result);
  100.                 }
  101.             } catch (SQLException ex) {
  102.                 if (reason == null) {
  103.                     reason = ex;
  104.                 }
  105.             }
  106.         }
  107.  
  108.         // if we got here nobody could connect.
  109.         if (reason != null)    {
  110.             println("getConnection failed: " + reason);
  111.             throw reason;
  112.         }
  113.  
  114.         println("getConnection: no suitable driver");
  115.         throw new SQLException("No suitable driver", "08001");
  116.     }
  117.  
  118.     /**
  119.      * Attempt to establish a connection to the given database URL.
  120.      * The DriverManager attempts to select an appropriate driver from
  121.      * the set of registered JDBC drivers.
  122.      *
  123.      * @param url a database url of the form jdbc:<em>subprotocol</em>:<em>subname</em>
  124.      * @param user the database user on whose behalf the Connection is being made
  125.      * @param password the user's password
  126.      * @return a Connection to the URL 
  127.      */
  128.     public static synchronized Connection getConnection(String url, 
  129.                     String user, String password) throws SQLException {
  130.         java.util.Properties info = new java.util.Properties();
  131.     if (user != null) {
  132.         info.put("user", user);
  133.     }
  134.     if (password != null) {
  135.         info.put("password", password);
  136.     }
  137.         return (getConnection(url, info));
  138.     }
  139.  
  140.     /**
  141.      * Attempt to establish a connection to the given database URL.
  142.      * The DriverManager attempts to select an appropriate driver from
  143.      * the set of registered JDBC drivers.
  144.      *
  145.      * @param url a database url of the form jdbc:<em>subprotocol</em>:<em>subname</em>
  146.      * @return a Connection to the URL 
  147.      */
  148.     public static synchronized Connection getConnection(String url) 
  149.                                     throws SQLException {
  150.         java.util.Properties info = new java.util.Properties();
  151.         return (getConnection(url, info));
  152.     }
  153.  
  154.     /**
  155.      * Attempt to locate a driver that understands the given URL.
  156.      * The DriverManager attempts to select an appropriate driver from
  157.      * the set of registered JDBC drivers. 
  158.      *
  159.      * @param url a database url of the form jdbc:<em>subprotocol</em>:<em>subname</em>
  160.      * @return a Driver that can connect to the URL 
  161.      */
  162.     public static Driver getDriver(String url) throws SQLException {
  163.         println("DriverManager.getDriver(\"" + url + "\")");
  164.  
  165.         if (!initialized) {
  166.             initialize();
  167.         }
  168.  
  169.         // Figure out the current security context.
  170.         Object currentSecurityContext = getSecurityContext();
  171.  
  172.         // Walk through the loaded drivers attempting to locate someone
  173.     // who understands the given URL.
  174.         for (int i = 0; i < drivers.size(); i++) {
  175.             DriverInfo di = (DriverInfo)drivers.elementAt(i);
  176.             // If the driver isn't part of the base system and doesn't come
  177.             // from the same security context as the current caller, skip it.
  178.             if (di.securityContext != null && 
  179.                         di.securityContext != currentSecurityContext) {
  180.                 println("    skipping: " + di);
  181.                 continue;
  182.             }
  183.             try {
  184.                 println("    trying " + di);
  185.         if (di.driver.acceptsURL(url)) {
  186.             // Success!
  187.                     println("getDriver returning " + di);
  188.                     return (di.driver);
  189.                 }
  190.             } catch (SQLException ex) {
  191.         // Drop through and try the next driver.
  192.             }
  193.         }
  194.  
  195.         println("getDriver: no suitable driver");
  196.         throw new SQLException("No suitable driver", "08001");
  197.     }
  198.  
  199.  
  200.     /**
  201.      * A newly loaded driver class should call registerDriver to make itself
  202.      * known to the DriverManager.
  203.      *
  204.      * @param driver the new JDBC Driver 
  205.      */
  206.     public static synchronized void registerDriver(java.sql.Driver driver)
  207.                         throws SQLException {
  208.         if (!initialized) {
  209.             initialize();
  210.         }
  211.         DriverInfo di = new DriverInfo();
  212.         di.driver = driver;
  213.         di.className = driver.getClass().getName();
  214.         // Note our current securityContext.
  215.         di.securityContext = getSecurityContext();
  216.         drivers.addElement(di);
  217.         println("registerDriver: " + di);
  218.     }
  219.  
  220.  
  221.     /**
  222.      * Drop a Driver from the DriverManager's list.  Applets can only
  223.      * deregister Drivers from their own classloader.
  224.      *
  225.      * @param driver the JDBC Driver to drop 
  226.      */
  227.     public static void deregisterDriver(Driver driver) throws SQLException {
  228.         // Figure out the current security context.
  229.         Object currentSecurityContext = getSecurityContext();
  230.         println("DriverManager.deregisterDriver: " + driver);
  231.  
  232.         // Walk through the loaded drivers.
  233.         int i;
  234.         DriverInfo di = null;
  235.         for (i = 0; i < drivers.size(); i++) {
  236.             di = (DriverInfo)drivers.elementAt(i);
  237.             if (di.driver == driver) {
  238.                 break;
  239.             }
  240.         }
  241.         // If we can't find the driver just return.
  242.         if (i >= drivers.size()) {
  243.             println("    couldn't find driver to unload");
  244.             return;
  245.         }
  246.  
  247.             // If an applet is trying to free a driver from somewhere else
  248.         // throw a security exception.
  249.         if (currentSecurityContext != null &&
  250.                 di.securityContext != currentSecurityContext) {
  251.             throw new SecurityException();
  252.         }
  253.  
  254.         // Remove the driver.  Other entries in drivers get shuffled down.
  255.         drivers.removeElementAt(i);
  256.     
  257.     }
  258.  
  259.     /**
  260.      * Return an Enumeration of all the currently loaded JDBC drivers
  261.      * which the current caller has access to.
  262.      *
  263.      * <P><B>Note:</B> The classname of a driver can be found using
  264.      * <CODE>d.getClass().getName()</CODE>
  265.      *
  266.      * @return the list of JDBC Drivers loaded by the caller's class loader
  267.      */
  268.     public static java.util.Enumeration getDrivers() {
  269.         java.util.Vector result = new java.util.Vector();
  270.  
  271.         if (!initialized) {
  272.             initialize();
  273.         }
  274.  
  275.         // Figure out the current security context.
  276.         Object currentSecurityContext = getSecurityContext();
  277.  
  278.         // Walk through the loaded drivers.
  279.         for (int i = 0; i < drivers.size(); i++) {
  280.             DriverInfo di = (DriverInfo)drivers.elementAt(i);
  281.             // if the driver isn't part of the base system and doesn't come
  282.             // from the same security context as the current caller, skip it.
  283.             if (di.securityContext != null && 
  284.                         di.securityContext != currentSecurityContext) {
  285.                 println("    skipping: " + di);
  286.                 continue;
  287.             }
  288.             result.addElement(di.driver);
  289.         }
  290.  
  291.         return (result.elements());
  292.     }
  293.  
  294.  
  295.     /**
  296.      * Set the maximum time in seconds that all drivers can wait
  297.      * when attempting to log in to a database.
  298.      *
  299.      * @param seconds the driver login time limit
  300.      */
  301.     public static void setLoginTimeout(int seconds) {
  302.         loginTimeout = seconds;
  303.     }
  304.  
  305.     /**
  306.      * Get the maximum time in seconds that all drivers can wait
  307.      * when attempting to log in to a database.
  308.      *
  309.      * @return the driver login time limit
  310.      */
  311.     public static int getLoginTimeout() {
  312.         return (loginTimeout);
  313.     }
  314.  
  315.  
  316.     /**
  317.      * Set the logging/tracing PrintStream that is used by the DriverManager
  318.      * and all drivers.
  319.      *
  320.      * @param out the new logging/tracing PrintStream; to disable, set to null
  321.      */
  322.     public static void setLogStream(java.io.PrintStream out) {
  323.         logStream = out;
  324.     }
  325.  
  326.     /**
  327.      * Get the logging/tracing PrintStream that is used by the DriverManager
  328.      * and all drivers.
  329.      *
  330.      * @return the logging/tracing PrintStream; if disabled, is null
  331.      */
  332.     public static java.io.PrintStream getLogStream() {
  333.         return (logStream);
  334.     }
  335.  
  336.     /**
  337.      * Print a message to the current JDBC log stream
  338.      *
  339.      * @param message a log or tracing message
  340.      */
  341.     public static void println(String message) {
  342.         if (logStream != null) {
  343.             logStream.println(message);
  344.         }
  345.     }
  346.  
  347.     //-------------------------------------------------------------------------
  348.  
  349.     private static Object getSecurityContext() {
  350.         // Get the securityContext for our caller.  For applets this
  351.         // will be the applet classloader base URL.
  352.         SecurityManager security = System.getSecurityManager();    
  353.         if (security == null) {
  354.             return (null);
  355.         }
  356.         return (security.getSecurityContext());
  357.     }
  358.  
  359.     private static void loadInitialDrivers() {
  360.         String drivers;
  361.         try {
  362.             drivers = System.getProperty("jdbc.drivers");
  363.         } catch (Exception ex) {
  364.             drivers = null;
  365.         }
  366.         println("DriverManager.initialize: jdbc.drivers = " + drivers);
  367.         if (drivers == null) {
  368.             return;
  369.         }
  370.         while (drivers.length() != 0) {
  371.             int x = drivers.indexOf(':');
  372.             String driver;
  373.             if (x < 0) {
  374.                 driver = drivers;
  375.                 drivers = "";
  376.             } else {
  377.                 driver = drivers.substring(0, x);
  378.                 drivers = drivers.substring(x+1);
  379.             }
  380.             if (driver.length() == 0) {
  381.                 continue;
  382.             }
  383.             try {
  384.                 println("DriverManager.Initialize: loading " + driver);
  385.                 Class.forName(driver);
  386.             } catch (Exception ex) {
  387.                 println("DriverManager.Initialize: load failed: " + ex);
  388.             }
  389.         }
  390.     }
  391.  
  392.     // Class initialization.
  393.     static void initialize() {
  394.         if (initialized) {
  395.             return;
  396.         }
  397.         initialized = true;
  398.         loadInitialDrivers();
  399.         println("JDBC DriverManager initialized");
  400.     }
  401.  
  402.     // Prevent the DriverManager class from being instantiated.
  403.     private DriverManager(){}
  404.  
  405.     private static java.util.Vector drivers = new java.util.Vector();
  406.     private static int loginTimeout = 0;
  407.     private static java.io.PrintStream logStream = null;
  408.     private static boolean initialized = false;
  409.  
  410. }
  411.  
  412.  
  413. // DriverInfo is a package-private support class.
  414. class DriverInfo {
  415.     Driver         driver;
  416.     Object        securityContext;
  417.     String        className;
  418.  
  419.     public String toString() {
  420.         return ("driver[className=" + className + ",context=" +
  421.         securityContext + "," + driver + "]");
  422.     }
  423. }
  424.